package main

import (
	"fmt"
	"sync"
)

type worker struct {
	id   int
	in   chan int
	done func()
}

func (w worker) doWork() {
	//for  {
	//	fmt.Printf("Worker %d received %d\n", i,<-c)
	//}
	//检查channel是否被close
	//for  {
	//	if n, ok := <-c; ok {
	//		fmt.Printf("Worker %d received %d\n", i,n)
	//	}
	//}
	//语法糖写法
	for n := range w.in {
		fmt.Printf("Worker %d received %d\n", w.id, n)
		w.done()
	}
}

// 这个channel只能用来收数据
func createWorker(i int, group *sync.WaitGroup) worker {
	//利用函数式的done巧妙利用闭包，避免了多次传参
	w := worker{
		i,
		make(chan int),
		func() {
			//表面上传了个函数，其实传了个闭包变量group
			group.Done()
		},
	}
	go w.doWork()
	return w
}

func main() {
	var workers [10]worker
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i, &wg)
	}
	wg.Add(10)
	for i, w := range workers {
		w.in <- i
	}
	wg.Wait()
}
